package org.example.gateway.config.properties;

import lombok.Data;
import org.example.common.core.utils.StringUtils;
import org.springframework.cloud.gateway.filter.FilterDefinition;
import org.springframework.cloud.gateway.handler.predicate.PredicateDefinition;
import org.springframework.http.server.PathContainer;
import org.springframework.util.CollectionUtils;
import org.springframework.web.util.pattern.PathPattern;
import org.springframework.web.util.pattern.PathPatternParser;

import javax.validation.Valid;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
import java.net.URI;
import java.util.*;

/**
 *资源鉴权名单配置
 */
@Data
public class AccessProperties{

    private String id;
    private @NotEmpty @Valid List<PredicateDefinition> predicates = new ArrayList();
    private @Valid List<FilterDefinition> filters = new ArrayList();
    private @NotNull URI uri;
    private Map<String, Object> metadata = new HashMap();
    private int order = 0;

    //鉴权开关
    private Boolean enabled=false;
    //权限多个,分割
    private String scope;
    //通过鉴权地址
    private Set<String> auth_urls;

    /**
     * 验证权限
     * @param in_scope
     * @return
     */
    public boolean isScope(Set<String> in_scope){
        if(this.enabled) {
            if(StringUtils.isEmpty(this.scope)) return true;
            return Arrays.asList(this.scope.split(",")).stream().anyMatch(s -> in_scope.contains(s));
        }
        return true;
    }

    /**
     * 验证访问地址权限
     * @param pathUrl
     * @return
     */
    public boolean isAuthUrls(String pathUrl){
        if(this.enabled){
            if(CollectionUtils.isEmpty(this.auth_urls)){
                this.auth_urls=new HashSet<>();
                this.auth_urls.add("/**");
            }
            return this.auth_urls.stream().anyMatch(url->{
                PathPattern pathPattern = PathPatternParser.defaultInstance.parse(url);
                PathContainer pathContainer = PathContainer.parsePath(pathUrl);
                return pathPattern.matches(pathContainer);
            });
        }
        return true;
    }

}
